package com.gitee.wsl.ext.collection


/**
 * Returns penultimate element.
 *
 * Throws: `NoSuchElementException` - if the list size is 1.
 */
fun <T> Iterable<T>.penultimate(): T {
    return when (this) {
        is List ->
            when (size) {
                0 -> throw NoSuchElementException("Collection is empty.")
                1 -> throw NoSuchElementException("Collection size is lower than 2.")
                else -> this[size - 2]
            }
        else -> {
            val iterator = iterator()
            if (!iterator.hasNext()) throw NoSuchElementException("Collection is empty.")
            iterator.next()
            if (!iterator.hasNext()) {
                throw NoSuchElementException("Collection size is lower than 2.")
            }
            var penultimate: T = iterator.next()
            while (iterator.hasNext()) {
                val next: T = iterator.next()
                if (iterator.hasNext()) penultimate = next
            }
            return penultimate
        }
    }
}

fun <T> Iterable<T>.penultimateOrNull(): T? {
    return when (this) {
        is List -> getOrNull(size - 2)
        else -> {
            val iterator = iterator()

            if (!iterator.hasNext()) return null
            iterator.next()
            if (!iterator.hasNext()) return null

            var penultimate: T = iterator.next()
            while (iterator.hasNext()) {
                val next: T = iterator.next()
                if (iterator.hasNext()) penultimate = next
            }
            return penultimate
        }
    }
}
